//
// Created by fairy on 2025/4/22 22:20.
//
#pragma once

#include <cstdint>
#include <type_traits>

namespace utils
{
    /**
     * @brief 硬件寄存器访问模板类
     * @tparam RegisterAddress 寄存器物理地址
     * @tparam RegisterType 寄存器类型（默认uint32_t），会出现结构体
     *
     * @details 提供类型安全的寄存器访问接口，支持原子操作和位操作
     */
    template<unsigned int RegisterAddress, typename RegisterType = unsigned int>
    requires (RegisterAddress >= 0x60000000)  // 典型的最小有效地址约束
    class fsmcRegister
    {
        using register_type = volatile RegisterType;

        static register_type* ptr(){return reinterpret_cast<register_type *>(RegisterAddress);}

    public:
        // 基础访问方法
        static void write(RegisterType value) noexcept
        {
            *ptr() = value;
        }

        static RegisterType read() noexcept{return *ptr();}
    };

    /**
     *
     * @tparam WordAddress 16位字地址
     * @tparam RegisterType
     */
    template<uint16_t WordAddress, typename RegisterType = uint16_t>
    class fpgaRegister
    {
        using register_type = volatile RegisterType;

        // fpga寄存器地址是16位，单片机是8位，所以需要左移一位，乘以2
        static register_type* ptr(){return reinterpret_cast<register_type *>(0x60000000 | (WordAddress<<1UL));}

    public:
        // 基础访问方法
        static void write(RegisterType value) noexcept
        {
            *ptr() = value;
        }
        static RegisterType read() noexcept{return *ptr();}
    };
}
